package se.gala.games.quetzalcoatl;

import java.util.HashSet;

import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.Image;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import se.gala.core.M3GMove;
import se.gala.utils.Coordinate2D;
import se.gala.utils.Logger;

public class GemButton extends ToggleButton {
	private HashSet<GemButton> matchingNeighbours = new HashSet<GemButton>();
	protected static GemButton lastClickedButton;
	/**
	 * Note that this might be different than the actual symbol from the matrix,
	 * as the real value might have been already updated.
	 */
	private QSymbols symbolCurrentlyDisaplayed;
	
	public GemButton(String text) {
		super(text);
	}
	
	public GemButton() {
		super();
		GemButton gb = this;
		
		gb.setOnMouseClicked(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				if (UIAnimationFactory.isOperationInProgress()) {
					setSelected(false);
					return;
				}
				
        		if (lastClickedButton != null) {
					gb.setMatchingNeighbours();
					lastClickedButton.setMatchingNeighbours();
					lastClickedButton.setSelected(false);
					if (gb.getMatchingNeighbours().contains(lastClickedButton)) {
		        		boolean betPlaced = UIQuetzalcoatl.doPlaceBet();
		        		if (!betPlaced) {
		        			gb.setSelected(false);
		        			return;
		        		} else {
							UIAnimationFactory.doSwapGemsAnimation(
									new M3GMove(gb.getCoordinates(),
											lastClickedButton.getCoordinates()),
									true, true, true);
		        		}
					}
				}
        		lastClickedButton = gb;
				if (gb.selectedProperty().get() == false) {
					lastClickedButton = null;
				}
			}

		});
		
		/* This is when the dragging starts, e.g. mouse is pressed and cursor moved. */
		gb.setOnDragDetected(new EventHandler<MouseEvent>() {
		    public void handle(MouseEvent event) {
				if (UIAnimationFactory.isOperationInProgress()) {
					setSelected(false);
					return;
				}
		    	lastClickedButton = gb;
		    	setMatchingNeighbours();
		    	UIQuetzalcoatl.higlightPossibleMatches(gb, true);
				QSymbols qs = getSymbolType();
		        Dragboard db = gb.startDragAndDrop(TransferMode.MOVE);
				ClipboardContent content = new ClipboardContent();
				content.putImage(new Image(UIQuetzalcoatl.resolveURI("img/"
						+ qs.getBg() + ".png")));
				db.setContent(content);
				setCursor(Cursor.NONE);
				
				gb.getStyleClass().remove(0);
				gb.getStyleClass().add(QSymbols.NONE.getStyleClass());
				gb.setStyle("-fx-background-color: rgba(" + qs.getColor() + ", 0.5)");
		        event.consume();
		    }
		});
		
		/* This is when the dragging is finished, e.g. the mouse is released */
		gb.setOnDragDone(new EventHandler <DragEvent>() {
	            public void handle(DragEvent event) {
			    	UIQuetzalcoatl.higlightPossibleMatches(gb, false);
					setCursor(Cursor.DEFAULT);
					gb.repaint();
	                event.consume();
	            }
	        });
		
		gb.setOnDragDropped(new EventHandler <DragEvent>() {
            public void handle(DragEvent event) {
            	if (event.getGestureSource() instanceof GemButton) {
	            	GemButton source = (GemButton) event.getGestureSource();
	            	/* Checks if the target is part of the matching neighbours */
	            	if (source.getMatchingNeighbours().contains(gb)) {
	            		boolean betPlaced = UIQuetzalcoatl.doPlaceBet();
	            		if (betPlaced) {
	            			double duration = UIAnimationFactory.doGemDraggedOverAnimation(gb, source);
		            		try { 
		            			Thread.sleep((long) (1000 * duration));
		            		} catch (InterruptedException e) {
		            			e.printStackTrace();
		            		}
		            		UIQuetzalcoatl.swapGems(source, gb);
		            		event.setDropCompleted(true);
		            		source.setHover(false);
		            		UIQuetzalcoatl.repaintGems();
		            		try { 
		            			Thread.sleep(50);
		            		} catch (InterruptedException e) {
		            			e.printStackTrace();
		            		}
		            		UIQuetzalcoatl.burnWinnings();
	            		}
	            	}
            	}                
                event.consume();
            }
        });
		
		gb.setOnDragOver(new EventHandler <DragEvent>() {
            public void handle(DragEvent event) {
            	if (event.getGestureSource() instanceof GemButton) {
	            	GemButton source = (GemButton) event.getGestureSource();
	            	if (source.getMatchingNeighbours().contains(gb)) {
	            		event.acceptTransferModes(TransferMode.MOVE);
	            	}
            	}                
                event.consume();
            }
        });
			
		gb.setOnDragExited(new EventHandler <DragEvent>() {
            public void handle(DragEvent event) {
            	if (event.getGestureSource() instanceof GemButton) {
            		gb.setHover(false);
            	}                
                event.consume();
            }
        });
	}
	
	protected void setHoverState(boolean value) {
		setHover(value);
	}
	
	protected QSymbols getSymbolCurrentlyDisaplayed() {
		return symbolCurrentlyDisaplayed;
	}
	
	public void setMatchingNeighbours() {
		matchingNeighbours = UIQuetzalcoatl.getPossibleMatches(this);
	}
	
	public HashSet<GemButton> getMatchingNeighbours() {
		return matchingNeighbours;
	}
	
	public void repaint() {
		this.matchingNeighbours.clear();
		this.setHover(false);
		this.setSelected(false);
		this.scaleXProperty().set(1);
		this.scaleYProperty().set(1);
		this.rotateProperty().set(0);
		repaintSymbolStyle();
	}
	
	protected void repaintSymbolStyle() {
        this.setStyle("");
		this.getStyleClass().remove(0);
		symbolCurrentlyDisaplayed = getSymbolType(); 
		this.getStyleClass().add(symbolCurrentlyDisaplayed.getStyleClass());	
	}
	
	@SuppressWarnings("unused")
	private static void log(Object o) {
		Logger.log(o);
	}
	
	protected QuetzalSymbol getQuetzalSymbol() {
		return (QuetzalSymbol) UIQuetzalcoatl.getGame().getMatrix()
				.getElementAt(this.getCoordinates());
	}
	
	protected QSymbols getSymbolType() {
		return (QSymbols) getQuetzalSymbol().getValue();
	}
	
	public String toString() {
		Coordinate2D c = this.getCoordinates();
		QuetzalSymbol s = (QuetzalSymbol) UIQuetzalcoatl.getGame().getMatrix().getElementAt(c);
		return "Gem:" + this.getText() + " " + s.getId() + "\t" + c + "\nend position: " + s.getOriginalCoordinate();
	}
	
	public Coordinate2D getCoordinates() {
		return new Coordinate2D(getId().substring(2), getId().substring(1, 2));
	}
	
}